/*
 * @Author: xiaosihan 
 * @Date: 2023-02-06 15:22:57 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2023-05-07 20:28:47
 */
import hashHistory from "@hashHistory";
import { AmbientLight, BoxGeometry, DirectionalLight, Euler, Mesh, MeshLambertMaterial, PointLight, Vector3, MeshPhongMaterial, DoubleSide } from "three";
import { degToRad } from "three/src/math/MathUtils";
import GLTF from "./component3d/GLTF/GLTF";
import Sky from "./component3d/Sky/Sky";
import ThreeBase from "three-base";
import threeUtils from "three-base/threeUtils";
import Transition from "three-base/Transition";
import KeyFrameAnimation from "three-base/KeyFrameAnimation";
import SpriteModal1 from "three-base/SpriteModal1";
import PlaneModal1 from "three-base/PlaneModal1";
import Text3D from "three-base/Text3D";
import road1PNG from "./img/road1.png";

import PlaneWithHtml from "three-base/PlaneWithHtml";
import SpriteWithHtml from "three-base/SpriteWithHtml";
import threeLoader from "three-base/threeLoader";
import ExtrudeMesh from "three-base/ExtrudeMesh";
import SpriteText2 from "three-base/SpriteText2";


/**
 *
 *
 * @class HomeRender
 * @extends {ThreeBase}
 */
class HomeRender extends ThreeBase {

    constructor() {
        super();
    }

    // 环境光
    ambientLight = (() => {
        const ambientLight = new AmbientLight("#fff", 1.5);
        this.scene.add(ambientLight);
        return ambientLight;
    })();

    //点光源
    pointLight = (() => {
        const pointLight = new PointLight("#fff", 1.5);
        pointLight.position.set(50, 40, 50);
        this.scene.add(pointLight);
        return pointLight;
    })();

    // 方向光
    directionalLight = (() => {
        const directionalLight = new DirectionalLight("#fff", 1.5);
        directionalLight.position.set(-10, 10, 5);
        directionalLight.target.position.set(0, 0, 0);
        directionalLight.castShadow = true;
        directionalLight.shadow.mapSize.set(1024, 1024);
        this.scene.add(directionalLight);
        return directionalLight;
    })();

    init() {
        super.init();

        // 开发模式时还原记录的位置
        if (threeUtils.isDev && localStorage.lookAt) {
            this.resetLookAt({
                ...JSON.parse(localStorage.lookAt)
            });
        }

        // 开发模式时记录当前的位置
        if (threeUtils.isDev) {
            this.controls.addEventListener("change", () => {
                localStorage.lookAt = JSON.stringify(this.getLookAt());
            })
        }

        if (threeUtils.isProd || (threeUtils.isDev && !localStorage.lookAt)) {
            this.resetLookAt({
                center: new Vector3(0, 0, 0),
                position: new Vector3(-7.049, 27.469, 59.276)
            });
        }

    }


    // 发光测试
    glow_test = (() => {
        const glow_test = new Text3D("glow_test");
        glow_test.scale.set(2, 2, 2);
        glow_test.position.set(-10, 8, 0);

        glow_test.userData = {
            glow_enable: true,//启用发光
            glow_color: "#04fa12",//发光颜色
            glow_width: 10,//发光厚度(像素)
        };

        this.scene.add(glow_test);
        return glow_test;
    })();

    // 描边测试
    stroke_test = (() => {
        const glow_test = new Text3D("stroke_test");
        glow_test.scale.set(2, 2, 2);
        glow_test.position.set(-10, 5, 0);

        glow_test.userData = {
            stroke_enable: true,//启用描边
            stroke_color: "#04fa12",//描边颜色
            stroke_width: 1,//描边厚度(像素)
        };

        this.scene.add(glow_test);
        return glow_test;
    })();

    box = (() => {
        const geometry = new BoxGeometry(5, 5, 5);
        const matearil = new MeshLambertMaterial({ color: 0xfff });
        const mesh = new Mesh(geometry, matearil);

        const transition = new Transition({ rotationY: 0 });

        // 动画对象播放回调
        transition.onChange(({ rotationY }) => {
            mesh.rotation.y = rotationY;
            this.needRender = true;
        });

        mesh.position.set(-10, 0, 0);
        mesh.userData = { cursor: "pointer", enableEvent: true };

        // 点击设置动画对象的值
        mesh.addEventListener("click", e => { });

        mesh.addEventListener("dbclick", e => {
            console.log("dbclick");
        });

        mesh.addEventListener("leftclick", e => {
            transition.set({ rotationY: Math.random() * 5 });
        });
        mesh.addEventListener("rightclick", e => {
            hashHistory.push("/home2");
        });
        mesh.addEventListener("mouseenter", e => { });
        mesh.addEventListener("mouseleave", e => { });
        mesh.addEventListener("mousemove", e => { });
        mesh.addEventListener("mousedown", e => { });
        mesh.addEventListener("mouseup", e => { });

        // 使用键盘修改模型的位置
        // keyContorls.addEventListener("change", e => {
        //     mesh.position.add(e.direction);
        //     console.log(mesh.position.toArray().join(" ,"));
        // });

        this.scene.add(mesh);
        return mesh;
    })();

    //天空
    sky = (() => {
        const sky = new Sky();
        this.scene.add(sky);
        return sky;
    })();


    // 加载 gltf
    gltf = (() => {
        const gltf = new GLTF();
        gltf.scale.set(10, 10, 10);
        gltf.position.set(20, 0, 0);
        this.scene.add(gltf);
        return gltf;
    })();


    //关键帧动画对象测试
    keyFrameAnimation = (() => {

        // 创建一个立方体
        const geometry = new BoxGeometry(5, 1, 5);
        const matearil = new MeshLambertMaterial({ color: "#f0f", wireframe: true });
        const mesh = new Mesh(geometry, matearil);

        //创建关键帧动画对象
        const keyFrameAnimation = new KeyFrameAnimation({
            object3d: mesh,
            keyframes: [
                { position: new Vector3(0, 0, 0), scale: new Vector3(1, 1, 1), rotation: new Euler(0, 0, 0), timeTemp: 0 },
                { position: new Vector3(0, 5, 1), scale: new Vector3(1, 1, 1), rotation: new Euler(0, degToRad(0), 0), timeTemp: 5000 },
                { position: new Vector3(0, 5, 5), scale: new Vector3(1, 1, 1), rotation: new Euler(0, degToRad(0), 0), timeTemp: 10000 },
            ]
        });

        // 当前
        keyFrameAnimation.addEventListener("update", () => {
            this.needRender = true;
        });

        this.scene.add(keyFrameAnimation);

        return keyFrameAnimation;
    })();

    //3D组件提示窗
    spriteModal1 = (() => {
        const spriteModal1 = new SpriteModal1();
        // 更新文本
        spriteModal1.updata({
            size: 10,
            title: "SpriteModal1",
            titleColor: "#ffffff",
            texts: [
                { text: "3D组件提示窗 SpriteModal1" },
                { text: "支持鼠标事件,自动换行,文字颜色,文字大小", color: "#ffff00" },
                { text: "使用\\n换行", color: "#00ffff" },
            ]
        })
        spriteModal1.userData = { cursor: "pointer", enableEvent: true };
        spriteModal1.addEventListener("leftclick", e => {
        });
        spriteModal1.position.set(-20, 0, 0);
        this.scene.add(spriteModal1);
        return spriteModal1;
    })();

    //3D平面组件提示窗
    planeModal1 = (() => {
        const planeModal1 = new PlaneModal1();
        // 更新文本
        planeModal1.updata({
            size: 10,
            title: "PlaneModal1",
            titleColor: "#ffffff",
            texts: [
                { text: "3D平面组件弹窗 PlaneModal1" },
                { text: "支持鼠标事件,自动换行,文字颜色,文字大小", color: "#ffff00" },
                { text: "使用\\n换行", color: "#00ffff" },
            ]
        })
        planeModal1.userData = { cursor: "pointer", enableEvent: true };
        planeModal1.addEventListener("leftclick", e => {
        });
        planeModal1.position.set(-30, 0, 0);
        this.scene.add(planeModal1);
        return planeModal1;
    })();

    // 3D文字
    text3D = (() => {
        const text3D = new Text3D("new Text3D\n3d文字组件");
        text3D.position.set(6, 2, 0);
        this.scene.add(text3D);
        return text3D;
    })();

    // htlml样式面板
    planeWithHtml = (() => {
        const planeWithHtml = new PlaneWithHtml(`
            <span style="font-family: 黑体;font-size:100px;color:#000;" >PlaneWithHtml</span>
            <br/>
            <span style="font-family: 黑体;font-size:100px;color:#f00;" >htlml文字组件</span>
        `);
        planeWithHtml.position.set(6, 6, 0);
        planeWithHtml.scale.set(0.01, 0.01, 0.01);
        planeWithHtml.rotateX(degToRad(90));


        //three事件
        planeWithHtml.userData = { cursor: "pointer", enableEvent: true };
        planeWithHtml.addEventListener("leftclick", e => { });

        this.scene.add(planeWithHtml);
        return planeWithHtml;
    })();

    // htlml样式面板
    spriteWithHtml = (() => {
        const spriteWithHtml = new SpriteWithHtml();

        spriteWithHtml.position.set(6, 9, 0);

        spriteWithHtml.setHtml(`
            <span style="font-family: 黑体;font-size:100px;color:#000;" >PlaneWithHtml</span>
            <br/>
            <span style="font-family: 黑体;font-size:100px;color:#f00;" >htlml文字组件</span>
        `).then(() => {
            spriteWithHtml.scale.multiplyScalar(0.01);
        });

        this.scene.add(spriteWithHtml);
        return spriteWithHtml;
    })();



    // 挤出公路模型
    extrudeMesh = (() => {
        const material = new MeshPhongMaterial({
            side: DoubleSide,
            map: threeLoader.getTexture(road1PNG)
        });
        const extrudeMesh = new ExtrudeMesh({
            paths: [
                // 挤出路径的点位置    转弯半径   转弯分段数     当前点的缩放            取个名字
                { vector3: [0, 0, -10], radius: 3, segments: 2, scale: { x: 1, y: 1 }, name: "路口1" },
                { vector3: [40, 0, -10], radius: 3, segments: 2, scale: { x: 1, y: 1 }, name: "路口1" },
                { vector3: [40, 0, 10], radius: 3, segments: 2, scale: { x: 1, y: 1 }, name: "路口1" },
                { vector3: [0, 0, 10], radius: 3, segments: 2, scale: { x: 1, y: 1 }, name: "路口1" },
            ], // 自动生成路径的
            shapePath: [[-2, 0], [2, 0]],// 被拉伸成模型的平面路径
            closed: false // 是否闭合路径
        }, material);
        this.scene.add(extrudeMesh);
        return extrudeMesh;
    })();

    // 精灵文字样式2
    spriteText2 = (() => {
        const spriteText2 = new SpriteText2("精灵文字2");
        //three事件
        spriteText2.userData = {
            cursor: "pointer",
            enableEvent: true,
        };
        spriteText2.addEventListener("leftclick", e => {
            if (spriteText2.text === "精灵文字2") {
                spriteText2.text = "SpriteText2";
            } else {
                spriteText2.text = "精灵文字2";
            }
        });

        spriteText2.padding = 1;
        spriteText2.backgroundColor = "rgba(0,0,0,0.5)";
        spriteText2.borderColor = "#fff000";
        spriteText2.borderWidth = 1;
        spriteText2.borderRadius = 4;
        spriteText2.position.set(0, 15, 0);
        this.scene.add(spriteText2);
        return spriteText2;
    })();

}


const homeRenderer = window.homeRenderer = new HomeRender();

export default homeRenderer;